package com.diao.myhub.config;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.io.File;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.List;

@Configuration
@Slf4j
public class MvcConfig implements WebMvcConfigurer {
    @Value("${upload.filepath}")
    private String uploadPath;
    private HandlerInterceptor loginInterceptor;
    @Autowired
    private ObjectMapper mapper;

    @Autowired
    @Qualifier(value = "loginInterceptor")
    public void setLoginInterceptor(HandlerInterceptor loginInterceptor) {
        this.loginInterceptor = loginInterceptor;
    }


    private UserInfoFlushInterceptor userInfoFlushInterceptor;

    @Autowired
    public void setUserInfoFlushInterceptor(UserInfoFlushInterceptor userInfoFlushInterceptor) {
        this.userInfoFlushInterceptor = userInfoFlushInterceptor;
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.removeIf(converter -> converter instanceof MappingJackson2HttpMessageConverter);
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setObjectMapper(mapper);
        converters.add(converter);
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**").order(2)
                .excludePathPatterns("/",
                        "/index.html",
                        "/vite.svg",
                        "/assets//**", "/index", "/login/**", "/callback", "/images/**",
                        "/main", "/js/**", "/css/**", "/fonts/**", "/error/**", "/swagger-ui/**", "/question/**",
                        "/questions/**", "/tag/**"
                        ,"/tag/admin/**", "/editor.md/**", "/uploadFiles/**", "/loginError/**", "/for-test/**");
        registry.addInterceptor(userInfoFlushInterceptor).addPathPatterns("/**").order(1);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
//        log.info(uploadPath);
        registry.addResourceHandler("/uploadFiles/**").addResourceLocations("file:" + uploadPath + File.separator);
    }

    @Bean
    public CorsFilter corsFilter() {
        //1. 添加 CORS 配置信息
        CorsConfiguration config = new CorsConfiguration();
        //放行哪些原始域，即哪些域名可以访问咋们的接口；* 表示所有，不限制；多个时反复添加即可；
        //注意 127.0.0.1 与 localhost 也会仍然不同的地址.
        config.addAllowedOrigin("http://localhost:63343");
        config.addAllowedOrigin("http://127.0.0.1:63343");
        config.addAllowedOrigin("http://localhost:5173");
        //是否发送 Cookie
        config.setAllowCredentials(true);
        //放行哪些请求方式，GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
        config.addAllowedMethod("*");
        config.addAllowedOriginPattern("*");
        config.addAllowedHeader("*");
        config.addExposedHeader("*");

        //放行哪些原始请求头部信息，不能设置 *: config.addAllowedHeader();
        //暴露哪些头部信息，不能设置 *: config.addExposedHeader();

        //2. 添加映射路径，即允许对方可以访问本应用下的哪些请求接口，/** 表示所有请求
        UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
        corsConfigurationSource.registerCorsConfiguration("/**", config);

        //3. 返回新的 CorsFilter
        return new CorsFilter(corsConfigurationSource);
    }
}
